﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
using Group16.Class_Library;
namespace Group16.Controller
{
    static public class PrintSupport
    {
        static private PrintDocument _document;
        static private PrintDocument Document
        { get { return _document; } }
        static PrintSupport()
        {
            _document = new PrintDocument();
            _document.PrintPage += print_PrintPage;
        }
        static public void PageSetup()
        {
            PageSetupDialog dlg = new PageSetupDialog();
            dlg.Document = Document;
            dlg.ShowDialog();
        }
        static public void PrintPreview()
        {
            PrintPreviewDialog dlg = new PrintPreviewDialog();
            dlg.Document = Document;
            dlg.ShowDialog();
        }
        /// <summary>
        /// In hoa don ra giay
        /// </summary>
        static public void Print()
        {
            PrintDialog dlg = new PrintDialog();
            dlg.Document = Document;
            if (dlg.ShowDialog() == DialogResult.OK)
                Document.Print();
        }
        static void print_PrintPage(object sender, PrintPageEventArgs e)
        {
            Form f = Application.OpenForms[0];
            //neu la form cha thi la form dang active
            if (f != null && f.IsMdiContainer)
                f = f.ActiveMdiChild;
            if (f is SaleForm)
            {
                SaleForm sf = (SaleForm)f;
                PrintInvoice(sf,e);
            }
            else if (f is IncomeStatement)
            {
                IncomeStatement inc = (IncomeStatement)f;
                PrintIncomeStatement(inc,e);
            }
            else
            {
                MessageBox.Show("Unable to print");
            }
        }



        static void PrintInvoice(SaleForm sf, PrintPageEventArgs e)
        {

            Customer info = sf.CustomInfomation;
            List<Device> Devices = sf.SoldDevices;
            Invoice invoice = sf.SaleInvoice;

            float left = e.MarginBounds.Left;
            float right = e.MarginBounds.Right;
            float top = e.MarginBounds.Top;
            float bottom = e.MarginBounds.Bottom;
            float printableWidth = e.MarginBounds.Width;

            Graphics g = e.Graphics;

            //print company's name
            Font font = new Font("Time New Roman", 18);
            float fontHeight = font.GetHeight(g);
            float xPos = left;
            float yPos = top + fontHeight;
            RectangleF area = new RectangleF(xPos, yPos, (right - xPos) * 2 / 5, bottom - yPos);
            string text = "Electronic Devices Group16 Cooperation";
            PrintText(g, font, text, ref area);

            //print invoice code
            font = new Font("Time New Roman", 13);
            text = invoice.InvoiceCode;
            float textWidth = g.MeasureString("MS: " + text, font).Width;
            xPos = right - textWidth;
            yPos = top + fontHeight;
            RectangleF areaMS = new RectangleF(xPos, yPos, textWidth + 10, bottom - yPos);
            PrintText(g, font, "MS:", text, areaMS);

            //print invoice's title
            font = new Font("Time New Roman", 20);
            fontHeight = font.GetHeight(g);
            text = "HÓA ĐƠN THIẾT BỊ ĐIỆN TỬ TIN HỌC";
            textWidth = g.MeasureString(text, font).Width;
            //yPos = top + fontHeight;
            xPos = (right - textWidth) / 2 + 10;
            yPos = area.Y + 20;
            area = new RectangleF(xPos + 15, yPos, textWidth + 30, bottom - yPos);
            PrintText(g, font, text, ref area);

            //print customer's name
            font = new Font("Time New Roman", 14);
            fontHeight = font.GetHeight(g);
            text = info.Name.ToUpperInvariant();
            textWidth = g.MeasureString("Họ và tên:" + text, font).Width;
            //yPos = top + fontHeight;
            xPos = left;
            yPos = area.Y + 15;
            area = new RectangleF(xPos, yPos + 20, textWidth + 30, bottom - yPos);
            PrintText(g, font, "Họ và tên:", text, ref area);

            //print customer's address
            font = new Font("Time New Roman", 14);
            fontHeight = font.GetHeight(g);
            text = info.Address.ToUpperInvariant();
            textWidth = g.MeasureString("Địa chỉ:" + text, font).Width;
            xPos = left;
            yPos = area.Y;
            float widthArea = right - xPos - 20;
            area = new RectangleF(xPos, yPos, widthArea, bottom - yPos);
            PrintText(g, font, "Địa chỉ:", text, ref area);

            //print customer's phone number
            font = new Font("Time New Roman", 14);
            fontHeight = font.GetHeight(g);
            text = info.Phone;
            textWidth = g.MeasureString("Số điện thoại:" + text, font).Width;
            //yPos = top + fontHeight;
            xPos = left;
            yPos = area.Y;
            area = new RectangleF(xPos, yPos, textWidth + 30, bottom - yPos);
            PrintText(g, font, "Số điện thoại:", text, ref area);

            foreach (Device d in Devices)
            {
                //print device's name
                font = new Font("Time New Roman", 14);
                fontHeight = font.GetHeight(g);
                text = d.Name;
                textWidth = g.MeasureString("Thiết bị:" + text, font).Width;
                //yPos = top + fontHeight;
                widthArea = right - xPos - 20;
                xPos = left;
                yPos = area.Y;
                area = new RectangleF(xPos, yPos, widthArea, bottom - yPos);
                PrintText(g, font, "Thiết bị:", text, ref area);
                //print device's name
                text = d.Cost.ToString();
                textWidth = g.MeasureString("Đơn giá:" + text + "000đ", font).Width;
                //yPos = top + fontHeight;
                xPos = area.X;
                yPos = area.Y - fontHeight;
                area = new RectangleF(xPos, yPos, textWidth + 20, bottom - yPos);
                PrintText(g, font, "Đơn giá:", text + "000đ", ref area);


                //print customer's phone number
                text = d.Discription;
                textWidth = g.MeasureString("Mô tả chi tiết:" + text, font).Width;
                //yPos = top + fontHeight;
                xPos = left;
                yPos = area.Y;
                widthArea = right - xPos - 20;
                area = new RectangleF(xPos, yPos, widthArea, bottom - yPos);
                PrintText(g, font, "Mô tả chi tiết:", text, ref area);
            }

            //print total cost
            text = "Total: " + invoice.Total.ToString() + "000đ";
            textWidth = g.MeasureString(text, font).Width;
            xPos = left;
            yPos = area.Y + 10;
            area = new RectangleF(xPos, yPos, textWidth + 30, bottom - yPos);
            PrintText(g, font, text, ref area);

            //print text "..."
            text = "Người lập hóa đơn";
            textWidth = g.MeasureString(text, font).Width;
            //yPos = top + fontHeight;
            xPos = left + 20;
            yPos = area.Y + 30;
            area = new RectangleF(xPos, yPos, textWidth + 30, bottom - yPos);
            PrintText(g, font, text, ref area);

            //print date made
            text = "Ngày " + invoice.DateMade.ToShortDateString();
            textWidth = g.MeasureString(text, font).Width;
            //yPos = top + fontHeight;
            xPos = right - textWidth;
            yPos = area.Y - fontHeight;
            area = new RectangleF(xPos, yPos, textWidth + 30, bottom - yPos);
            PrintText(g, font, text, ref area);

            //print text "..."
            text = "Khách hàng";
            textWidth = g.MeasureString(text, font).Width;
            //yPos = top + fontHeight;
            xPos = right - textWidth - 20;
            yPos = area.Y;
            area = new RectangleF(xPos, yPos, textWidth + 20, bottom - yPos);
            PrintText(g, font, text, ref area);


        }
        static void PrintIncomeStatement(IncomeStatement inc, PrintPageEventArgs e)
        {
            float left = e.MarginBounds.Left;
            float right = e.MarginBounds.Right;
            float top = e.MarginBounds.Top;
            float bottom = e.MarginBounds.Bottom;
            float printableWidth = e.MarginBounds.Width;

            Graphics g = e.Graphics;

            //print company's name
            Font font = new Font("Time New Roman", 18);
            float fontHeight = font.GetHeight(g);
            float xPos = left;
            float yPos = top + fontHeight;
            RectangleF area = new RectangleF(xPos, yPos, (right - xPos) * 2 / 5, bottom - yPos);
            string text = "Electronic Devices Group16 Cooperation";
            PrintText(g, font, text, ref area);
            //print date make
            font = new Font("Time New Roman", 13);
            text = "Date made:" + DateTime.Now.ToShortDateString();
            float textWidth = g.MeasureString(text, font).Width;
            xPos = right - textWidth;
            yPos = top + fontHeight;
            RectangleF areaDM = new RectangleF(xPos, yPos, textWidth + 10, bottom - yPos);
            PrintText(g, font, text,ref areaDM);

            //print invoice's title
            font = new Font("Time New Roman", 20);
            fontHeight = font.GetHeight(g);
            text = "INCOME STATEMENT";
            textWidth = g.MeasureString(text, font).Width;
            //yPos = top + fontHeight;
            xPos = (right - textWidth) / 2 + 30;
            yPos = area.Y + 20;
            area = new RectangleF(xPos + 15, yPos, textWidth + 30, bottom - yPos);
            PrintText(g, font, text, ref area);

            //print start date
            font = new Font("Time New Roman", 16);
            fontHeight = font.GetHeight(g);
            text = "From: " + inc.StartDate.ToShortDateString();
            textWidth = g.MeasureString(text, font).Width;
            xPos = left;
            yPos = area.Y + 40;
            area = new RectangleF(xPos, yPos, textWidth + 30, bottom - yPos);
            PrintText(g, font, text, ref area);

            //print end date
            text = "To: " + inc.EndDate.ToShortDateString();
            textWidth = g.MeasureString(text, font).Width;
            xPos = left;
            yPos = area.Y + 10;
            area = new RectangleF(xPos, yPos, textWidth + 30, bottom - yPos);
            PrintText(g, font, text, ref area);

            //print gross income
            text = "Gross income: " + inc.GrossIncome.ToString() + "000đ";
            textWidth = g.MeasureString(text, font).Width;
            xPos = left;
            yPos = area.Y + 10;
            area = new RectangleF(xPos, yPos, textWidth + 30, bottom - yPos);
            PrintText(g, font, text, ref area);
            //print 
            //print text "..."
            text = "Chairman";
            textWidth = g.MeasureString(text, font).Width;
            //yPos = top + fontHeight;
            xPos = left + 20;
            yPos = area.Y + 30;
            area = new RectangleF(xPos, yPos, textWidth + 30, bottom - yPos);
            PrintText(g, font, text, ref area);

            //print date made
            text = "Date " + DateTime.Now.ToShortDateString();
            textWidth = g.MeasureString(text, font).Width;
            //yPos = top + fontHeight;
            xPos = right - textWidth;
            yPos = area.Y - fontHeight;
            area = new RectangleF(xPos, yPos, textWidth + 30, bottom - yPos);
            PrintText(g, font, text, ref area);

            //print text "..."
            text = "Employee";
            textWidth = g.MeasureString(text, font).Width;
            //yPos = top + fontHeight;
            xPos = right - textWidth - 20;
            yPos = area.Y;
            area = new RectangleF(xPos, yPos, textWidth + 20, bottom - yPos);
            PrintText(g, font, text, ref area);

        }
        static private void PrintText(Graphics g, Font font,string title, string text,ref RectangleF area)
        {
            float left = area.Left;
            float right = area.Right;
            float top = area.Top;
            float bottom = area.Bottom;
            float fontHeight = font.GetHeight(g);
            float xPos = area.Left;
            float yPos = top + fontHeight;

            float spaceWidth = g.MeasureString(" ", font).Width;
            float titleWidth = g.MeasureString(title, font).Width;

            if (!area.Contains(xPos, yPos))
            {
                throw new Exception("Cannot print");
                //TODO:them page moi
            }

            g.DrawString(title, font, Brushes.Red, new PointF(xPos, yPos));
            left += titleWidth + spaceWidth;
            xPos = left;
            string[] words = text.Split(" \t\n\r\0".ToArray());
            foreach(string word in words)
            {
                float wordWidth = g.MeasureString(word,font).Width;
                if (wordWidth == 0.0)
                    continue;
                if (xPos + wordWidth >= right)
                {
                    xPos = left;
                    yPos += fontHeight;
                    if(xPos > bottom)
                    {
                        //TODO:Open new page
                        break;
                    }

                }
                g.DrawString(word,font,Brushes.Red,new PointF(xPos,yPos));
                xPos += wordWidth;
            }
            area.Y = yPos;
            area.X = xPos;
        }

        static private void PrintText(Graphics g, Font font, string title, string text, RectangleF area)
        {
            float left = area.Left;
            float right = area.Right;
            float top = area.Top;
            float bottom = area.Bottom;
            float fontHeight = font.GetHeight(g);
            float xPos = left;
            float yPos = top + fontHeight;

            float spaceWidth = g.MeasureString(" ", font).Width;
            float titleWidth = g.MeasureString(title, font).Width;

            if (!area.Contains(xPos, yPos))
            {
                throw new Exception("Cannot print");
                //TODO:them page moi
            }

            g.DrawString(title, font, Brushes.Red, new PointF(xPos, yPos));
            left += titleWidth + spaceWidth;
            xPos = left;
            string[] words = text.Split(" \t\n\r\0".ToArray());
            foreach (string word in words)
            {
                float wordWidth = g.MeasureString(word, font).Width;
                if (wordWidth == 0.0)
                    continue;
                if (xPos + wordWidth >= right)
                {
                    xPos = left;
                    yPos += fontHeight;
                    if (xPos > bottom)
                    {
                        //TODO:Open new page
                        break;
                    }

                }
                g.DrawString(word, font, Brushes.Red, new PointF(xPos, yPos));
                xPos += wordWidth;
            }
        }
        static private void PrintText(Graphics g, Font font, string text, ref RectangleF area)
        {
            float left = area.Left;
            float right = area.Right;
            float top = area.Top;
            float bottom = area.Bottom;
            float fontHeight = font.GetHeight(g);
            float xPos = left;
            float yPos = top + fontHeight;
            
            if (!area.Contains(xPos, yPos))
            {
                throw new Exception("Cannot print");
                //TODO:them page moi
            }
            string[] words = text.Split(" \t\n\r\0".ToArray());
            foreach (string word in words)
            {
                float wordWidth = g.MeasureString(word, font).Width;
                if (wordWidth == 0.0)
                    continue;
                if (xPos + wordWidth >= right)
                {
                    xPos = left;
                    yPos += fontHeight;
                    if (xPos > bottom)
                    {
                        //TODO:Open new page
                        break;
                    }

                }
                g.DrawString(word, font, Brushes.Red, new PointF(xPos, yPos));
                xPos += wordWidth;
            }
            area.Y = yPos;
            area.X = xPos;
        }
    }
}
